using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Galplay {
  public class GalScene {
    public int EventID { get; }
    public string Name { get; }
    public List<GalScript> Scripts { get; private set; }

    public GalScene(string name, XmlReader xml) {
      EventID = 0;
      Name = name;

      // 读取脚本
      var items = xml.Root.GetNodes("Item");
      if (items == null) {
        Scripts = new List<GalScript>();
        Debuger.LogError($"{name} has not Item nodes.");
      }else{
        ReadScripts(items);
      }

    }


    // 通过一个Node初始化，这是将GalScene设置为一个Event
    public GalScene(XmlNode node) {
      EventID = node.GetInt("Id");
      Name = node.GetStr("Name");
      // 读取脚本
      ReadScripts(node.GetNodes("Item"));
    }


    private void ReadScripts(List<XmlNode> items) {
      Scripts = new List<GalScript>(items.Count);
      foreach (XmlNode item in items) {
        var script = CreateScript(item);
        if (script != null) {
          script.Index = Scripts.Count;
          Scripts.Add(script);
        }
      }
    }

    // 获取此索引前最近的一个类型
    public GalScript GetLastBefore(int index, ScriptType type) {
      var start_index = index;

      while (index > 0) {
        index--;
        var s = GetLine(index);
        if (s.Type == type) {
          return s;
        }
      }
      // 如果向前找不到就向后找
      index = start_index;
      while (index < (Scripts.Count - 1)) {
        index++;
        var s = GetLine(index);
        if (s.Type == type) {
          return s;
        }
      }

      return null;
    }

    // 通过一个索引得到脚本
    public GalScript GetLine(int index) {
      if (index < 0 || index >= Scripts.Count) {
        return null;
      }
      return Scripts[index];
    }

    private GalScript CreateScript(XmlNode item) {
      var type = GalScript.GetScriptTypeByName(item.GetStr("Type"));
      switch (type) {
        case ScriptType.Picture:
          return new ScriptPicture(this, item);
        case ScriptType.Clear:
          return new ScriptClear(this, item);
        case ScriptType.Wait:
          return new ScriptWait(this, item);
        case ScriptType.Text:
          return new ScriptText(this, item);
        case ScriptType.Command:
          return new ScriptCommand(this, item);
        case ScriptType.Event:
          return new ScriptEvent(this, item);
        case ScriptType.BGM:
          return new ScriptBGM(this, item);
        case ScriptType.BG:
          return new ScriptBG(this, item);
        case ScriptType.BGS:
          return new ScriptBGS(this, item);
        case ScriptType.SE:
          return new ScriptSE(this, item);
        case ScriptType.Tint:
          return new ScriptTint(this, item);
        case ScriptType.Comment:
        default: // 包括未知类型和未处理的情况
          return null;
          //return new ScriptComment(this, item);
      }
    }
  }
}